#ifndef MYSERIALPORT_H
#define MYSERIALPORT_H
#include <QQueue>
#include <QSerialPort>

enum class ExcuteType {
  LED = 1 << 1,
  STEERING = 1 << 2,
  FAN = 1 << 3,
  RELAY = 1 << 4,
  STEP = 1 << 5,

  TEST_EX = 0,

  ALL_EXCUTE = LED | STEERING | FAN | RELAY
};

class QTimer;

class MySerialPort : public QSerialPort {
  Q_OBJECT
public:
  MySerialPort();

  QStringList getPortLists();

  void request_sensor();

  void request_excute(ExcuteType type, double value1, double value2 = 0.0);

  void step_on(bool open_step);

protected slots:
  /**
   * @brief 接受下位机的串口数据
   */
  void readyReadSlot();
  /**
   * @brief 定时出队并发给下位机
   */
  void sendTimeoutSlot();
  /**
   * @brief 定时将拉去请求入队
   */
  void appendTimeoutSlot();
  void stepTimerSlot();

protected:
  void handleData(const QByteArray &data);
  /**
   * @brief 处理从串口发来的数据帧
   * @param data
   */
  void handleFrame(const QByteArray &data);

  QByteArray temp;

  QTimer *sendTimer;
  QTimer *appendTimer;
  QTimer *stepTimer;

  QQueue<QByteArray> sendList;

private:
  struct LEDState {
    int l1 = 0, l2 = 0, l3 = 0, l4 = 0;
    bool led_on = false; // 是否有led打开
  private:
    [[maybe_unused]] bool padding[3];
  } led_state;
  /**
   * @brief 步进电机状态，前进方向为正
   */
  struct StepState {
    bool is_on = false;

    bool is_front = true;

  private:
    [[maybe_unused]] bool __padding_bool__[2];

  public:
    int distance = 0;
    int step = 0;

    static const int MAX_DIS = 720;
    static const int MAX_STEP = 6;

  } step_state;
};

#ifndef SG_SERIALPORT
#define SG_SERIALPORT() singleton<MySerialPort>::getInstance()
#endif

#endif // MYSERIALPORT_H
